import os
import math
import time
import pygame as pg
from ombot import neuron
# import neuron

pg.init()
pg.font.init()
font = pg.font.SysFont('Times New Roman', 10)
color = pg.Color('dodgerblue2')


class Robot:
    def __init__(self, win, x=11, y=50, width=12, height=18, h_speed=8):
        self.win = win
        # self.display=display
        self.frame = 0

        self.x = x
        self.y = y
        self.width = width
        self.height = height
        self.h_speed = h_speed

        self.v_speed = 10
        self.HIGHEST = 1
        self.LOWEST = 45

        self.RUNNING = 0
        self.RISING = 1
        self.FALLING = 2
        self.state = self.RUNNING

        self.land = False  # only when it fall to the ground

        # collision sense value
        self.collision = -1  # the index of obs. -1:no collsion
        self.n_collisions = 0  # num of collisons

        # distance sense value
        self.distance = 10.0  # the distance between the robot and the nearest obs
        self.obs = -1  # the index of nearest obs. -1: no obs
        self.obs_width = 0.1  # the width of nearest obs

        # nerual contorller
        self.neuron = neuron.Neuron(self.win)
        # self.neuron = neuron.Neuron(self.display)

    def reset(self):
        self.x = 11
        self.y = 54

        self.land = False

        self.collision = -1
        self.n_collisions = 0

        self.distance = 10.0
        self.obs = -1
        self.obs_width = 0.1

        self.neuron.reset()

    # set robot position
    def move(self, x, y):
        self.x = x
        self.y = y

    def show(self, show_x):
        # collisions number
        text = font.render("c:", True, color)
        self.win.blit(text, (80, 0))
        # self.display.text("c:", 80, 0, 1)

        text1 = font.render("c:", True, color)
        self.win.blit(text1, (100, 0))
        # self.display.text(str(self.n_collisions), 100, 0, 1)

        # collision sensor
        if self.collision != -1:
            text = font.render("Collision!!!", True, color)
            self.win.blit(text, (10, 20))
            # self.display.text("Collision!!!", 10, 20, 1)
            # time.sleep(1)
            return

        # robot figure
        # self.display.rect(self.x-show_x-self.width//2, self.y-self.height//2, self.width, self.height, 1)
        text = font.render("o", True, color)
        self.win.blit(text, (self.x - show_x - self.width // 2 + 2, self.y - self.height // 2))
        # self.display.text("o", self.x - show_x - self.width // 2 + 2, self.y - self.height // 2, 1)

        if self.frame == 0 and self.state == self.RUNNING:
            text = font.render("M", True, color)
            self.win.blit(text, (self.x - show_x - self.width // 2, self.y - self.height // 2 + 8))
            # self.display.text("M", self.x - show_x - self.width // 2, self.y - self.height // 2 + 8, 1)
        else:
            text = font.render("V", True, color)
            self.win.blit(text, (self.x - show_x - self.width // 2, self.y - self.height // 2 + 8))
            # self.display.text("V", self.x - show_x - self.width // 2, self.y - self.height // 2 + 8, 1)
        self.frame = not self.frame

        # distance sensor
        text = font.render("d:", True, color)
        self.win.blit(text, (30, 10))
        # self.display.text("d:", 30, 10, 1)

        text = font.render(str(self.distance), True, color)
        self.win.blit(text, (60, 10))
        # self.display.text(str(self.distance), 60, 10, 1)

        text = font.render("w:", True, color)
        self.win.blit(text, (30, 20))
        # self.display.text("w:", 30, 20, 1)

        text = font.render(str(self.obs_width), True, color)
        self.win.blit(text, (60, 20))
        # self.display.text(str(self.obs_width), 60, 20, 1)

    def jump(self):
        if self.state == self.RUNNING:
            self.state = self.RISING

    def run(self, h_speed):
        self.h_speed = h_speed

    def update(self):
        self.x += self.h_speed

        self.land = False
        if self.state == self.RISING:
            self.y -= self.v_speed
            if self.y <= self.HIGHEST:
                self.state = self.FALLING
        elif self.state == self.FALLING:
            self.y += self.v_speed
            if self.y >= self.LOWEST:
                self.state = self.RUNNING
                self.land = True

    def think(self):
        if self.neuron.get(self.distance, self.obs_width):
            self.jump()

    def learn(self, human_command):
        full = False
        if self.state == self.RUNNING:  # robot must be on groud
            if human_command == 1:
                self.jump()
                full = self.neuron.feed(self.distance, self.obs_width, 1)
            else:
                if int.from_bytes(os.urandom(1), 'big') < 80:  # p=0.3 as a sample
                    full = self.neuron.feed(self.distance, self.obs_width, 0)
        return full
